#ifndef _MODE_H_
#define _MODE_H_
#include <string>
#include <math.h>

enum Dimension
{
    One = 1,
    Two = 2
};

#define DIM_NAMESPACE(dim) dim##Dim

Dimension string2Dimension(const std::string &str);
std::string Dimension2string(const Dimension &dimension);

template <typename Ts>
inline Ts pow(Ts l, Dimension r)
{
    return pow(l, (Ts)r);
}

enum BoundType
{
    Dirichlet = 1,
    Neumann = 2
};

BoundType string2BoundType(const std::string &str);
std::string BoundType2string(const BoundType &boundType);

enum Insqaure
{
    Inside = 0,
    Up = 3,
    Right = 2,
    Down = 4,
    Left = 1,
    Vertex = 5 // 顶点
};

// BoundName string2BoundName(const std::string &str);

enum CycleChoice
{
    Vcycle = 1,
    FMG = 2
};

CycleChoice string2CycleChoice(const std::string &str);
std::string CycleChoice2string(const CycleChoice &cycleChoice);

namespace Operators
{
    enum Restriction
    {
        Injection = 1,
        FullWeighting = 2
    };
    enum Interpolation
    {
        Linear = 1,
        Qudratic = 2
    };
    Restriction string2Restriction(const std::string &str);
    std::string Restriction2string(const Restriction &restriction);
    Interpolation string2Interpolation(const std::string &str);
    std::string Interpolation2string(const Interpolation &interpolation);
}

inline int getN(int size, Dimension dim)
{
    switch (dim)
    {
    case One:
        return size - 1;
        break;
    case Two:
        return sqrt(size) - 1;
        break;
    default:
        return size - 1;
        break;
    }
}

#endif